/**
 * 模块化。可扩展，封装，暴露接口
 * Created by KY on 2017/8/18.
 */
define('comps/audio', ['art', 'text!tpl/comps/audio.tpl', 'ldfw/utils/format', 'css!assets/css/comps/audio.css'],
function (art, tpl) {
    return {
        init: function ($el, options) {
            const defaultoptions = {
                musicSupport: window.HTMLAudioElement ? true : false,
                autoplay: false,
                musicSrc: ''
            };
            function Audio($context, options) {
                this.$el = $context;
                this.currentState = 'pause';
                this.duration = null;
                this.timer = null;
                this.settings = $.extend(true, defaultoptions, options);
                this.init();
            }
            Audio.prototype = {
                init: function () {
                    let self = this;
                    self.voiceid = uuid('')
                    self.global = {
                        canDragBar: true,
                        barDraging: false
                    }
                    self.checkAudioRight(function(){
                        self.render()
                        self.initEvent()
                    },function(){
                        self.$el.find('.share_audio_context').hide()
                    })
                },
                checkAudioRight:function(success,fail){
                    var settings = this.settings
                    if(settings.musicSrc.startsWith('blob')){
                        success && success()
                    }else{
                        var request = new XMLHttpRequest()
                        request.open('GET', settings.musicSrc, true);
                        request.responseType = 'arraybuffer';
                        request.onreadystatechange=function(){
                            if(request.readyState ===4) {
                                if (request.status == 200 || request.status == 304) {
                                    success && success()
                                }else{
                                    fail && fail()
                                }
                            }
                        }
                        request.send()
                    }
                },
                render: function () {
                    let self = this,
                        settings = $.extend(true, self.settings, {
                            voiceid: self.voiceid
                        });
                    self.$el.html(art.compile(tpl)(settings))
                    self.$audio = self.$el.find('audio')
                    self.audio = self.$audio[0]
                    self.audio.src = settings.musicSrc
                    self.$audio_progress_wrp = self.$el.find('.share_audio_progress_wrp')
                    self.$audio_progress = self.$el.find('.share_audio_progress_inner')
                    self.$audio_progress_handle = self.$el.find('.share_audio_progress_handle')
                    self.$audio_context = self.$el.find('.share_audio_context')
                    self.$audio_length_total = self.$el.find('.share_audio_length_total')
                    self.$audio_length_current = self.$el.find('.share_audio_length_current')
                },
                play: function () {
                    let self = this;
                    if (self.currentState === "play") {
                        self.pause();
                        return;
                    }
                    self.audio.play();
                    clearInterval(self.timer)
                    self.timer = setInterval(self.run.bind(self), 50);
                    self.currentState = "play";
                    self.$audio_context.addClass('share_audio_playing');
                },
                pause: function () {
                    let self = this;
                    self.audio.pause();
                    self.currentState = "pause";
                    clearInterval(self.timer);
                    self.$audio_context.removeClass('share_audio_playing');
                },

                initEvent: function () {
                    let self = this;
                    let updateTime = self.duration ? true : false
                    self.audio.onerror = function(e){
                        console.error(e.target.error)
                    }
                    self.audio.oncanplay = function(){
                        console.log('可以播放了')
                    }
                    self.$audio_context.on('click', function () {
                        self.play();
                        if (!updateTime) {
                            self.updateTotalTime();
                            updateTime = true;
                        }
                    });
                    self.audio.addEventListener('loadeddata',function(){
                        self.updateTotalTime()
                        if (self.settings.autoplay) {
                            self.play()
                        }
                    })
                    self.dargEvent()
                },
                //正在播放
                run: function () {
                    let self = this;
                    if(!self.global.barDraging){
                        self.updateCurrentTime()
                        self.animateProgressBarPosition();
                    }
                    if (self.audio.ended) {
                        self.pause();
                    }
                },
                //进度条
                animateProgressBarPosition: function () {
                    let self = this,
                        percentage = (self.audio.currentTime * 100 / self.audio.duration) + '%';
                    if (percentage == "NaN%") {
                        percentage = 0 + '%';
                    }
                    let styles = {
                        "width": percentage
                    };

                    self.$audio_progress.css(styles);
                    self.$audio_progress_handle.css({left:percentage,display:"block"})
                },
                //获取时间秒
                getAudioSeconds: function (string) {
                    let self = this
                    string = string % 60;
                    string = self.addZero(Math.floor(string), 2);
                    (string < 60) ? string = string : string = "00";
                    return string;
                },
                //获取时间分
                getAudioMinutes: function (string) {
                    let self = this
                    string = string / 60;
                    string = self.addZero(Math.floor(string), 2);
                    (string < 60) ? string = string : string = "00";
                    return string;
                },
                //时间+0
                addZero: function (word, howManyZero) {
                    word = String(word);
                    while (word.length < howManyZero) word = "0" + word;
                    return word;
                },
                //更新总时间
                updateTotalTime: function () {
                    let self = this,
                        time = self.audio.duration,
                        minutes = self.getAudioMinutes(time),
                        seconds = self.getAudioSeconds(time),
                        audioTime = minutes + ":" + seconds;
                    self.$audio_length_total.text(audioTime);
                    self.duration = audioTime
                },

                updateCurrentTime: function (time) {
                    let self = this
                    time = time || self.audio.currentTime
                    let minutes = self.getAudioMinutes(time),
                        seconds = self.getAudioSeconds(time),
                        currentTime = minutes + ":" + seconds;
                    self.$audio_length_current.text(currentTime);
                },
                dargEvent: function () {
                    let self = this
                    let global = self.global;
                    let duration = self.audio.duration || 0
                    let i = self.$audio_progress_wrp[0],
                        offsetLeft = 0;
                    while (i && i !=document.body) {
                        offsetLeft += i.offsetLeft
                        i = i.offsetParent
                    }
                    global.seekData = {
                        downX: 0,
                        dragTime: 0,
                        duration: duration,
                        moveX: 0,
                        offsetLeft: offsetLeft,
                        rangeWidth: self.$audio_progress_wrp[0].offsetWidth,
                        startTime: 0
                    }
                    self.$audio_progress_wrp.on('mousedown', function (e) {

                        if(global.canDragBar){
                            self._pointerDownHandler({
                                x: e.pageX || e.clientX
                            })
                            e.preventDefault()
                        }
                    })
                    self.$audio_progress_wrp.on('touchstart', function (e) {
                        if(global.canDragBar){
                            self._pointerDownHandler({
                                x: e.changedTouches[0].clientX
                            })
                            e.preventDefault()
                        }
                    })
                    self.$audio_progress_wrp.on('touchmove', function (e) {
                        if (global.canDragBar && global.barDraging) {
                            self._pointerMoveHandler({
                                x: e.changedTouches[0].clientX
                            })
                            e.preventDefault()
                            e.stopPropagation()
                        }
                    })
                    self.$audio_progress_wrp.on('touchend', function (e) {
                        if (global.canDragBar && global.barDraging) {
                            self._pointerUpHandler({
                                x: e.changedTouches[0].clientX
                            })
                            e.preventDefault()
                            e.stopPropagation()
                        }
                        return
                    })
                    self.$audio_context.on('mousemove', function (e) {
                        if(global.canDragBar && global.barDraging){
                            self._pointerDownHandler({
                                x: e.pageX || e.clientX
                            })
                            e.preventDefault()
                            e.stopPropagation()
                        }
                    })
                    $('body').on('mouseup', function (e) {
                        if (global.canDragBar && global.barDraging) {
                            self._pointerUpHandler({
                                x: e.pageX || e.clientX
                            })
                            e.preventDefault()
                            e.stopPropagation()
                        }
                        return
                    })
                },
                _pointerDownHandler:function(e) {
                    let t = this.global;
                    t.barDraging = true
                    t.seekData.downX = e.x
                    t.seekData.duration = this.audio.duration
                    t.seekData.startTime = this.audio.currentTime
                },
                _pointerMoveHandler: function(e) {
                    let t = this.global,
                        o = t.seekData;
                    o.moveX = e.x;
                    var r = (o.moveX - o.offsetLeft) / o.rangeWidth;
                    r = Math.min(r, 1),
                        r = Math.max(r, 0),
                        o.dragTime = r * o.duration,
                    o.dragTime != o.startTime && this._updateProgressBar(o.dragTime);
                },
                _pointerUpHandler :function(e) {
                    let self = this,
                        t = this.global,
                        o = t.seekData;
                    o.dragTime || this._pointerMoveHandler({
                        x: e.x
                    })
                    t.barDraging = false
                    self.seek(o.dragTime)
                    t.seekData.startTime = 0
                    t.seekData.dragTime = 0
                    t.seekData.downX = 0
                    t.seekData.moveX = 0
                },
                _updateProgressBar:function(time){
                    let self = this,
                        percentage = (time * 100 / self.audio.duration) + '%';
                    if (percentage == "NaN%") {
                        percentage = 0 + '%';
                    }
                    let styles = {
                        "width": percentage
                    }
                    self.$audio_progress.css(styles);
                    self.$audio_progress_handle.css({left:percentage,display:"block"})
                    self.updateCurrentTime(time)
                },
                seek:function(time){
                    time = parseInt(time,10);
                    time = Math.min(time,this.global.seekData.duration)
                    this.audio.currentTime = time
                }
            }
            let audio = new Audio($el, options)
            return audio
        }
    }
})

